﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using CarparkIMS_Model;
using AutoMapper;
using CarparkIMS_CMS.Infrastructure.Mapper;
using CarparkIMS_CMS.Models;
using Microsoft.AspNetCore.Authorization;
using CarparkBusiness;
using Newtonsoft.Json.Linq;
namespace CarparkIMS_CMS.Controllers
{
    public class CamerasettingController : Controller
    {
        private readonly IMSContext _context;
        private readonly IMapper _mapper;

        public CamerasettingController(IMSContext context)
        {
            _context = context;
            _mapper = AutoMapperConfiguration.Mapper;
        }

        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Index()
        {
            BackgroundServiceStatus bgService = BackgroundServiceStatus.Get();
            ViewBag.BackgroundServiceStatus = bgService;
            var query = await _context.llqqCameraDoorMapping.Include(a=>a.Door).ToListAsync();
            var model = _mapper.Map<List<CameraConfigModel>>(query);
            return View(model);
        }

        // GET: CameraSetting/Details/5
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var llqqCameraDoorMapping = await _context.llqqCameraDoorMapping.Include(a=>a.Door)
                .FirstOrDefaultAsync(m => m.ID == id);
            if (llqqCameraDoorMapping == null)
            {
                return NotFound();
            }

            var model = _mapper.Map<CameraConfigModel>(llqqCameraDoorMapping);
            model.DoorList = (await _context.tbDoor.ToListAsync()).Select(a=> new SelectListItem { 
                Text = a.Name,
                Value = a.DoorID.ToString()
            }).ToList();
            return View(model);
        }

        // GET: CameraSetting/Create
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Create()
        {
            CameraConfigModel model = new CameraConfigModel();
            model.DoorList = (await _context.tbDoor.ToListAsync()).Select(a => new SelectListItem
            {
                Text = a.Name,
                Value = a.DoorID.ToString()
            }).ToList();
            return View(model);
        }

        // POST: CameraSetting/Create
        // To protect from overposting attacks, enable the specific properties you want to bind to, for 
        // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Create([Bind("CameraIP,DoorID,TransactionTypeID,Deleted,ParkingPlaceId,ParkingPlaceSharpNumber")] llqqCameraDoorMapping llqqCameraDoorMapping)
        {
            if (_context.llqqCameraDoorMapping.Where(a => !a.Deleted && a.CameraIP == llqqCameraDoorMapping.CameraIP).Any())
            {
                ModelState.AddModelError("CameraIP", "Camera Added");
            }

            if (ModelState.IsValid)
            {
                int id = _context.llqqCameraDoorMapping.Max(s => s.ID) + 1;
                llqqCameraDoorMapping.ParkingPlaceId = id.ToString();
                _context.Add(llqqCameraDoorMapping);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            var model = _mapper.Map<CameraConfigModel>(llqqCameraDoorMapping);
            model.DoorList = (await _context.tbDoor.ToListAsync()).Select(a => new SelectListItem
            {
                Text = a.Name,
                Value = a.DoorID.ToString()
            }).ToList();
            return View(model);
        }

        // GET: CameraSetting/Edit/5
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var llqqCameraDoorMapping = await _context.llqqCameraDoorMapping.FindAsync(id);
            if (llqqCameraDoorMapping == null)
            {
                return NotFound();
            }
            var model = _mapper.Map<CameraConfigModel>(llqqCameraDoorMapping);
            model.DoorList = (await _context.tbDoor.ToListAsync()).Select(a => new SelectListItem
            {
                Text = a.Name,
                Value = a.DoorID.ToString()
            }).ToList();
            return View(model);
        }
         
        [HttpPost] 
        public async Task<IActionResult> Edit(int id, [Bind("ID,CameraIP,DoorID,TransactionTypeID,Deleted,ParkingPlaceId,ParkingPlaceSharpNumber")] llqqCameraDoorMapping llqqCameraDoorMapping)
        {
            if (id != llqqCameraDoorMapping.ID)
            {
                return NotFound();
            }
            if (_context.llqqCameraDoorMapping.Where(a => !a.Deleted && a.CameraIP == llqqCameraDoorMapping.CameraIP && a.ID != llqqCameraDoorMapping.ID).Any())
            {
                ModelState.AddModelError("CameraIP", "Camera Added");
            }
            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(llqqCameraDoorMapping);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!llqqCameraDoorMappingExists(llqqCameraDoorMapping.ID))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            var model = _mapper.Map<CameraConfigModel>(llqqCameraDoorMapping);
            model.DoorList = (await _context.tbDoor.ToListAsync()).Select(a => new SelectListItem
            {
                Text = a.Name,
                Value = a.DoorID.ToString()
            }).ToList();
            return View(model);
        }

        // GET: CameraSetting/Delete/5
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var llqqCameraDoorMapping = await _context.llqqCameraDoorMapping.Include(a=>a.Door)
                .FirstOrDefaultAsync(m => m.ID == id);
            if (llqqCameraDoorMapping == null)
            {
                return NotFound();
            }

            var model = _mapper.Map<CameraConfigModel>(llqqCameraDoorMapping);
            model.DoorList = (await _context.tbDoor.ToListAsync()).Select(a => new SelectListItem
            {
                Text = a.Name,
                Value = a.DoorID.ToString()
            }).ToList();
            return View(model);
        }

        // POST: CameraSetting/Delete/5
        [HttpPost, ActionName("Delete")] 
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var llqqCameraDoorMapping = await _context.llqqCameraDoorMapping.FindAsync(id);
            _context.llqqCameraDoorMapping.Remove(llqqCameraDoorMapping);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        private bool llqqCameraDoorMappingExists(int id)
        {
            return _context.llqqCameraDoorMapping.Any(e => e.ID == id);
        }

        [HttpGet]
        [Route("GetParkingSetting")]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> GetParkingSetting()
        {
            ParkingSetting setting = new ParkingSetting();
            if (ParkingSetting.Get() != null)
            {
                setting = ParkingSetting.Get();
            }

            ParkingSetting parkingSettingX = new ParkingSetting
            {
                AllowanceSeconds = setting.AllowanceSeconds,
                HistDateBegin = setting.HistDateBegin,
                HistoryRecordRemain = setting.HistoryRecordRemain,
                IntervalMinutes = setting.IntervalMinutes,
                IntervalSeconds = setting.IntervalSeconds,
                IntervalTimes = setting.IntervalTimes,
                MaxIntervalTimes = setting.MaxIntervalTimes,
                MinTimesValid = setting.MinTimesValid,
                OnlyRegistered = setting.OnlyRegistered
            };

            await Task.Delay(1);
            return View(parkingSettingX);
        }
        [HttpPost] 
        [Route("GetParkingSetting")]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> GetParkingSetting(ParkingSetting setting)
        {
            ResponseModalX responseModalX = new ResponseModalX
            {
                meta = new MetaModalX { ErrorCode = -1, Message = "FAIL " + $"{DateTime.Now:yyyy-MM-dd HH:mm:ss fff}", Success = false },
                data = null
            };

            if (setting == null)
            {
                return Ok(responseModalX);
            }

            await Task.Delay(0);

            ParkingSetting parkingSetting = new ParkingSetting
            {
                AllowanceSeconds = setting.AllowanceSeconds,
                HistDateBegin = setting.HistDateBegin,
                HistoryRecordRemain = setting.HistoryRecordRemain,
                IntervalMinutes = setting.IntervalMinutes,
                IntervalSeconds = setting.IntervalSeconds,
                IntervalTimes = setting.IntervalTimes,
                MaxIntervalTimes = setting.MaxIntervalTimes,
                MinTimesValid = setting.MinTimesValid,
                OnlyRegistered = setting.OnlyRegistered
            };

            bool ret = ParkingSetting.Save(parkingSetting);

            responseModalX.meta = new MetaModalX { ErrorCode = -1, Message = "OK" + $"{DateTime.Now:yyyy-MM-dd HH:mm:ss fff} [Hist:{setting.HistDateBegin}] [InsMins:{setting.IntervalMinutes}] [MaxTs:{setting.MaxIntervalTimes}]", Success = ret };
            responseModalX.data = parkingSetting;

            if (!ret)
            {
                responseModalX.meta.Message = "Fail";
                responseModalX.meta.ErrorCode = 0;
            }
            return Ok(responseModalX);
        }
         
        [HttpGet]
        [Route("ParkingSettingJson")]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> ParkingSettingJson()
        {
            ParkingSetting parkingSetting = new ParkingSetting();
            if (ParkingSetting.Get() != null)
            {
                parkingSetting = ParkingSetting.Get();
            }
            await Task.Delay(1);
            return Ok(parkingSetting);
        }
    }
}
